package com.scs.application.modules.wm.service;

import com.scs.application.core.service.IBaseService;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.entity.StockLock;
import com.scs.application.modules.wm.enums.LockBusType;
import com.scs.application.modules.wm.enums.UniqueCodeType;

import java.io.Serializable;
import java.util.List;

/**
 * <p>
 * 库存锁定 Service
 * </p>
 */

public interface StockLockService extends IBaseService<StockLock> {

    /**
     * 一物一码方式锁库
     *
     * @param busType：业务类型，取自枚举类  LockBusType
     * @param busValue：业务单据主键
     * @param warehouseId：库存记录所在仓库ID
     * @param uc：唯一码标识
     * @param ucType：唯一码类型,方法判断 UniqueCodeUtils.getUniqueCodeType(uniqueCode)
     * @return 锁定成功后的库存ID
     */
    String lock(LockBusType busType, Serializable busValue, String warehouseId, String uc, UniqueCodeType ucType, String lockComment);

    /**
     * 非一物一码方式锁库
     *
     * @param busType：业务类型
     * @param busValue：业务关键字
     * @param warehouseId：仓库ID
     * @param matrId：物料ID
     * @param qty：锁定数量
     * @param lockComment：锁定说明
     * @return 锁定库存ID列表
     */
    List<String> lock(LockBusType busType, Serializable busValue, String warehouseId, String matrId, Double qty, String lot, String lockComment);

    /**
     * 解锁
     *
     * @param stockId：锁定时返回的StockId
     */
    void unlock(String stockId);

    /**
     * 解锁，并指定是否合并库存
     *
     * @param stockId：锁定时返回的StockId
     * @param flagMergeStock：解锁后是否合并库存
     */
    void unlock(String stockId, Boolean flagMergeStock);

    /**
     * 一物一码解锁
     *
     * @param uc：唯一码
     * @param ucType：唯一码类型
     */
    void unlock(String uc, UniqueCodeType ucType, String warehouseId);

    /**
     * 不要求分拆库存的不返回库存记录，不用提供锁定说明
     *
     * @param busType：业务类型
     * @param busValue： 业务关键字
     * @param warehouseId： 仓库ID
     * @param matrId：物料ID
     * @param qty：锁定数量
     * @return 锁定Id
     */
    String virtualLock(LockBusType busType, Serializable busValue, String warehouseId, String matrId, Double qty);

    /**
     * 解除虚拟锁
     *
     * @param busType：业务类型
     * @param busValue：业务关键字
     * @param warehouseId：仓库ID
     */
    void virtualUnlock(LockBusType busType, Serializable busValue, String warehouseId);

    /**
     * 解除虚拟锁集合
     *
     * @param busType：业务类型
     * @param busValues：业务关键字
     * @param warehouseId：仓库ID集合
     */
    void virtualUnlockList(LockBusType busType, List<String> busValues, String warehouseId);

    /**
     * 查询虚拟锁
     *
     * @param busType：业务类型
     * @param busValue：业务关键字
     * @param warehouseId：仓库ID
     * @return 查询到的虚拟锁实体
     */
    StockLock getVirtualLock(LockBusType busType, Serializable busValue, String warehouseId);

    /**
     * 查询虚拟锁集合
     *
     * @param busType：业务类型
     * @param busValues：业务关键字集合
     * @param warehouseId：仓库ID
     * @return 查询到的虚拟锁实体
     */
    List <StockLock> getVirtualLockList(LockBusType busType, List<String> busValues, String warehouseId);
    /**
     * 扣减虚拟锁（典型业务场景，拣货时）
     *
     * @param stockLockId：虚拟锁ID
     * @param qty：数量
     */
    void reduceVirtualLock(String stockLockId, Double qty);

    /**
     * 扣减虚拟锁（典型业务场景，拣货时）
     *
     * @param busType：业务类型
     * @param busValue：业务关键字
     * @param warehouseId：仓库ID
     * @param qty
     */
    void reduceVirtualLock(LockBusType busType, Serializable busValue, String warehouseId, Double qty);

    /**
     * 增加虚拟锁（典型业务场景，移除拣货明细时）
     *
     * @param stockLockId：虚拟锁ID
     * @param qty：数量
     */
    void addVirtualLock(String stockLockId, Double qty);

    /**
     * 增加虚拟锁（典型业务场景，移除拣货明细时）
     *
     * @param busType：业务类型
     * @param busValue：业务关键字
     * @param warehouseId：仓库ID
     * @param qty: 数量
     */
    void addVirtualLock(LockBusType busType, Serializable busValue, String warehouseId, Double qty);

    List<Stock> lockBatch(LockBusType busType, String busValue, String warehouseId, String lockComment, List<String> snList,String refBusType);

    List<Stock> unlockBatch(List<String> snList);

    List<Stock> unlockBatchWithBusKeyValue(List<String> snList, String busKeyValue);

    // 更新数量锁
    void updateLockQty(String stockId, String busKeyValue, Double lockQty);

    // 获取某个库存已锁定数量
    Double getLockQty(String stockId);
}
